﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MVCPets.Data;
using MVCPets.Extensions.MVC;
using MVCPets.Extensions;
using System.ComponentModel;
using System.Web.Security;
using MVCPets.Data.Model;

namespace MVCPets.Models
{
  public class UserModel
  {
    #region Public Members
    public SelectList Roles { get; set; }    
    [DisplayName("First Name")]
    public string FirstName { get; set; }
    [DisplayName("Last Name")]
    public string LastName { get; set; }
    [DisplayName("Email")]
    public string EmailAddress { get; set; }
    [DisplayName("Registration Date")]
    public DateTime RegistrationDate { get; set; }
    public string Password { get; set; }    
    public int Role { get; set; }
    [DisplayName("Role")]
    public string RoleName { get; set; }
    public int? ID { get; set; }
    #endregion

    #region Constructors
    public UserModel()
    {
      GetRolesList();
    }

    public UserModel(int id)
    {
      var user = Data.DataAccess.DataStore.LoadObject<User>(id);

      if (user != null)
      {
        this.EmailAddress = user.EmailAddress;
        this.FirstName = user.FirstName;
        this.ID = user.ID;
        this.LastName = user.LastName;
        this.RegistrationDate = user.RegistrationDate;
        this.Role = user.Role;
        this.RoleName = RoleModel.GetRole(user.Role).RoleName;

        GetRolesList(user.ID);
      }   
    }
    #endregion

    #region Static Methods
    public static List<UserModel> GetUsers()
    {
      List<UserModel> ret = new List<UserModel>();
      foreach (var r in Data.DataAccess.DataStore.LoadEntireTable<User>())
        ret.Add(new UserModel()
          {
            ID = r.ID,
            FirstName = r.FirstName,
            LastName = r.LastName,
            EmailAddress = r.EmailAddress,
            RegistrationDate = r.RegistrationDate,
            Role = r.Role,
            RoleName = RoleModel.GetRole(r.Role).RoleName
          });

      return ret;
    }

    public static int GetUserRole(string email)
    {
      var ret = int.MaxValue;

      User u = Data.DataAccess.DataStore.Query<User>()
          .Where(r => r.EmailAddress == email)
          .FirstOrDefault();

      if(u != null)
      {
        ret = RoleModel.GetRole(u.Role).RoleValue;
      }
      return ret;
    }

    public static UserModel GetUser(string email, bool online)
    {
      UserModel ret = null;
      User r = Data.DataAccess.DataStore.Query<User>().Where(x => x.EmailAddress == email).FirstOrDefault();
      if (r != null)
      {
        ret = new UserModel
          {
            ID = r.ID,
            FirstName = r.FirstName,
            LastName = r.LastName,
            EmailAddress = r.EmailAddress,
            RegistrationDate = r.RegistrationDate,
            Role = r.Role,
            RoleName = RoleModel.GetRole(r.Role).RoleName
          };
      }
      return ret;
    }

    public static bool ValidateUser(string email, string password)
    {
      var ret = false;
      ret = Data.DataAccess.DataStore.Query<User>().Where(r => r.EmailAddress == email && r.Password == password.Encrypt()).Count() > 0;
      return ret;
    }

    public static bool ChangePassword(string email, string oldPassword, string newPassword)
    {
      var ret = false;

      return ret;
    }

    public static MembershipCreateStatus CreateUser(string email, string password)
    {
      var ret = MembershipCreateStatus.UserRejected;
      var role = Data.DataAccess.DataStore.Query<Role>().Where(R => R.RoleName == "Commenter").First().ID;
      if(Data.DataAccess.DataStore.InsertObject(new User()
        {
          EmailAddress = email,
          Password = password.Encrypt(),
          Role = role,
          RegistrationDate = DateTime.Now.ToUniversalTime()
        }))
      {
        ret = MembershipCreateStatus.Success;
      }
      return ret;
    }
    #endregion

    #region Public Methods
    public bool ChangePassword(string oldPassword, string newPassword)
    {
      var ret = false;

      return ret;
    }

    public bool Save()
    {
      var ret = false;

      if (this.ID.HasValue) ret = Update();
      else ret = Insert();

      return ret;
    }

    public bool Delete()
    {
      return Data.DataAccess.DataStore.DeleteObject<User>(this.ID);
    }
    #endregion

    #region Private Methods
    private bool Insert()
    {
      return Data.DataAccess.DataStore.InsertObject(new User()
        {
          EmailAddress = this.EmailAddress,
          FirstName = this.FirstName,
          LastName = this.LastName,
          Password = this.Password.Encrypt(),
          RegistrationDate = DateTime.Now.ToUniversalTime(),
          Role = this.Role
        }); 
    }

    private bool Update()
    {
      User u = Data.DataAccess.DataStore.LoadObject<User>(this.ID);
      u.FirstName = this.FirstName;
      u.EmailAddress = this.EmailAddress;
      u.LastName = this.LastName;
      u.Role = this.Role;
      return Data.DataAccess.DataStore.UpdateObject(u);
    }

    private void GetRolesList()
    {
      Roles = new SelectList(Data.DataAccess.DataStore.LoadEntireTable<Role>().OrderBy(r => r.RoleName).ToList(), "id", "RoleName");
    }

    private void GetRolesList(int id)
    {
      Roles = new SelectList(Data.DataAccess.DataStore.LoadEntireTable<Role>().OrderBy(R=> R.RoleName), "id", "RoleName", id);
    }
    #endregion
  }
}